/*
 * Topol.h
 *
 *  Created on: May 12, 2012
 *      Author: marchi
 */

#ifndef TOPOL_H_
#define TOPOL_H_
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <sstream>
#include <map>
#include "ResidueTypes.h"
#include "MyUtilClass.h"
#include "Groups.h"
#include "Myradius.h"

using namespace DVECT;

using std::vector;
using std::string;
using std::cout;
using std::endl;
using std::map;
using std::pair;
namespace Topol_NS {
enum {Slt, Sol};

class MySubunit{
	bool b;
	string c;
	int n;
public:
	MySubunit(){b=false;c=' ';n=-1;};
	MySubunit(bool b1, string c1): n(-1) {
		b=b1;c=c1;
	}
	bool isHydrophobic(MySubunit a){
		if(c != a.c &&(b==true && a.b == true)) return true;
		return false;
	}
	bool isHydrophilic(MySubunit a){
		if(c != a.c &&(b==false && a.b == false)) return true;
		return false;
	}
	bool isMixed(MySubunit a){
		if(c != a.c) {
			if(b == true && a.b == false) return true;
			if(b == false && a.b == true) return true;
		}
		return false;
	}

	void putN(int m){n=m;};
	void putB(bool b0){b=b0;};
	void putC(string c0){c=c0;};
	string getC(){return c;};
	bool getB(){return b;};
	int getN(){return n;};
};
class Topol {
	size_t nr;
	size_t nres;
	size_t maxtype;
	vector<string> atomname;
	vector<string> resinfo;
	vector<int> resind;
	vector<vector<int> > cidx;
	vector<string> TypeNames;
	vector<double> rd;
	vector<int> bG;
	vector<int> ResType;
	vector<string> restype_s;
	vector<int> restype_i;
	int bGMax;
	vector<vector<int> > vG;
	vector<MySubunit> MySub;
	map<string,vector<int> > DefDomain;

	void ExtractInfo(const vector<string> & data,bool);
	void FindGroups(vector<Dvect> &,int);
	void AllignGroups(vector<Dvect> &,int &,vector<int>&,int );
public:
	static std::ofstream * fDomainPDB;
	static bool bAuto;
	static bool bDefDomain;
	Topol();
	Topol(const vector<string> &, bool);
	Topol & operator()(const vector<string> &,bool);
	virtual ~Topol();
	size_t Size(){return nr;}
	size_t ResSize(){return nres;}
	int ResIndex(const int n){return resind[n];};
	unsigned int getCidxSize(){return cidx.size();}
	const vector<int> & getCidx(const size_t n){return cidx[n];}

	const vector<string> & getAtomName(){return atomname;}
	const string * getTypeNames(){return &TypeNames[0];};
	void setrdtoone(){for(unsigned int n=0;n<rd.size();n++) rd[n]=1.0;}
	vector<string> & getrestype_s(){return restype_s;};
	vector<int> & getResType(){return ResType;};
	vector<int> & getrestype_i(){return restype_i;};
	string AtomInfo(size_t n){
		try {if(n>=nr) throw "Atom number beyond bounds ";}
		catch(const char * s){cout << s << n << " larger than " << nr << endl;exit(1);}
		return atomname[n];
	}
	string AtomResidue(int n){
		try {if(static_cast<size_t> (n) >=nr) throw "Atom number beyond bounds ";}
		catch(const char * s){cout << s << n << " larger than " << nr << endl;exit(1);}
		return resinfo[resind[n]];
	}
	string ResInfo(size_t n){
		try {if(n>=nres) throw "Residue number beyond bounds ";}
		catch(const char * s){cout << s << endl;exit(1);}
		return resinfo[n];
	}
	vector<double> & getrd(){return rd;};
	vector<MySubunit> & getMySub(){
		return MySub;
	};
	int getmaxt(){return maxtype;}
	const vector<int> & gbG(){return bG;};
	int gbGMax(){return bGMax;}
	const vector<vector<int> > & gvG(){return vG;};
	void AddDomain(const string & a, const vector<int> & b){
		DefDomain[a]=b;
	}
};

} /* namespace Topol_NS */
#endif /* TOPOL_H_ */
